package cn.lisens.modules.sys.interceptor;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 日志拦截器
 * @author FastSun
 * @date 2024年8月21日
 */
public class LoggerInterceptor implements HandlerInterceptor {
	
	private static Logger logger = LoggerFactory.getLogger(LoggerInterceptor.class);
	private static final ThreadLocal<Long> startTimeThreadLocal =
			new NamedThreadLocal<Long>("LoggerInterceptor StartTime");

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		long beginTime = System.currentTimeMillis();
		startTimeThreadLocal.set(beginTime);
		logger.debug("[preHandle]请求开始 URI: {}",  request.getRequestURI() + getParameters(request));
		logger.info("[preHandle][" + request + "]" + "[" + request.getMethod()
	      + "]" + request.getRequestURI() + getParameters(request));
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		logger.info("[postHandle][" + request + "]");
	}
	
	@Override
	public void afterCompletion(
	  HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
	  throws Exception {
	    if (ex != null){
	        ex.printStackTrace();
	    }
	    long endTime = System.currentTimeMillis();
		long startTime = 0; // 得到线程绑定的局部变量（开始时间）
	    if (startTimeThreadLocal != null){
			Long time = startTimeThreadLocal.get();
			if (time != null){
				startTime = time;
			}
			startTimeThreadLocal.remove(); // 用完之后销毁线程变量数据
		}
	    long executeTime = endTime - startTime;	//执行时间
	    logger.info("[afterCompletion]请求完成 URI: {}, 用时: {}ms", 
	    		request.getRequestURI(),executeTime);
	    logger.info("[afterCompletion][" + request + "][executeTime:"+executeTime+"][exception: " + ex + "]");
	}
	
	private String getParameters(HttpServletRequest request) {
	    StringBuffer posted = new StringBuffer();
	    Enumeration<?> e = request.getParameterNames();
	    if (e != null) {
	        posted.append("?");
	    }
	    while (e.hasMoreElements()) {
	        if (posted.length() > 1) {
	            posted.append("&");
	        }
	        String curr = (String) e.nextElement();
	        posted.append(curr + "=");
	        if (curr.contains("password") 
	          || curr.contains("pass")
	          || curr.contains("pwd")) {
	            posted.append("*****");
	        } else {
	            posted.append(request.getParameter(curr));
	        }
	    }
	    String ip = request.getHeader("X-FORWARDED-FOR");
	    String ipAddr = (ip == null) ? getRemoteAddr(request) : ip;
	    if (ipAddr!=null && !ipAddr.equals("")) {
	        posted.append("&_psip=" + ipAddr); 
	    }
	    return posted.toString();
	}
	
	private String getRemoteAddr(HttpServletRequest request) {
	    String ipFromHeader = request.getHeader("X-FORWARDED-FOR");
	    if (ipFromHeader != null && ipFromHeader.length() > 0) {
	        logger.debug("ip from proxy - X-FORWARDED-FOR : " + ipFromHeader);
	        return ipFromHeader;
	    }
	    return request.getRemoteAddr();
	}
}
